//
//  "$Id: System.h 105579 2013-03-12 09:14:52Z zhao_zhiding $"
//
//  Copyright (c)1992-2007, ZheJiang Dahua Technology Stock CO.LTD.
//  All Rights Reserved.
//
//	Description:	
//	Revisions:		Year-Month-Day  SVN-Author  Modification
//

#ifndef __SYSTEM_API_H__
#define __SYSTEM_API_H__

#include "Types.h"
#include "System3.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup SystemAPI API System
/// 系统时间设置，关机与重启，系统资源状况，升级等API。
/// @{

/// 系统信息，1024字节
typedef struct SystemInfo
{
	/// 处理器型号
	char processor[32];

	/// 设备序列号
	char serialNumber[32];

	/// 设备型号，格式为type_serials，比如设备类型为IPC_F725。
	char deviceType[32];

	/// 硬件版本，格式为xx.xx，主辅版本各使用2位数字表示，主版本的高位0需省略，
	/// 比如版本号为1.00。
	char hardwareVersion[8];

	/// 应用程序是否自动启动，用来判断设备是否是调试状态版本
	char appAutoStart;

	/// 0-支持云台功能，1-不支持云台功能
	char noPtz;

	/// 0-支持SD卡，1-不支持SD卡
	char noSdCard;

	///0-开启智能算法，1-未开启智能算法
	char noIVS;

	/// 设备类型，比如设备类型为IPC。
	char deviceClass[32];

	/// 处理器数量
	char processorCount;

	/// 0-支持RTC，1-不支持RTC
	char noRTC;

	/// 0-支持CMOS，1-不支持CMOS
	char noCMOS;

	/// 0-不支持4g, 1-支持4g
	char wireless;

	/// 设备带宽能力，单位 Mbps
	/// 486、432M ARM主频，带宽为32M；300M ARM主频，带宽为24M；270M ARM主频，带宽为16M；216M ARM主频，带宽为12M
	int  bandWidth;

	/// 设备关键字，用于区别同系的不同设备型号。
	/// 100w: 100w设备 130w: 130w设备 200w: 200w设备 300w:设备 400w: 400w设备 500w: 500w设备
	char deviceKey[16];

	/// flash大小
	ulong flashSize;

	/// 保留
	char reserved[856];
}SystemInfo;

/// 内存信息，128字节
typedef struct MemoryInfo
{
	ulong total;	///< 总共内存大小，以Kilo-Bytes为单位。
	ulong free;		///< 剩余内存大小，以Kilo-Bytes为单位。
	char reserved[120];		///< 保留
}MemoryInfo;

/// 性能统计信息
typedef struct PerformanceInfo
{
	ulong CPUUsagePercent;	///< CPU利用率百分比
	ulong contextSwitches;	///< 上下文切换次数
	float CPUTemperature;	///< CPU温度
	char reserved[116];		///< 保留
}PerformanceInfo;


/// 得到系统信息
/// 得到系统内存信息。
/// 
/// \param [out] info 指向系统信息结构SystemInfo的指针。
/// \retval 0  获取成功。
/// \retval <0  获取失败。
int getSystemInfo(SystemInfo * info);


/// 得到系统性能信息。
/// 
/// \param [out] info 指向系统性能信息结构PerformanceInfo的指针。
/// \retval 0  获取成功。
/// \retval <0  获取失败。
int getPerformanceInfo(PerformanceInfo * info);


/// 得到系统内存信息。
/// 
/// \param [out] info 指向系统内存信息结构MemoryInfo的指针。
/// \retval 0  获取成功。
/// \retval <0  获取失败。
int getMemoryInfo(MemoryInfo * info);


/// 让系统蜂鸣器发出单音调的声音，是同步模式，时间到才返回。
/// 
/// \param [in] frequence 音调频率。
/// \param [in] duration 持续的时间，毫秒为单位。
void beep(ulong frequence, ulong duration );


/// 系统复位
void rebootSystem(void);


/// 系统关闭。
void shutdownSystem(void);


/// 系统恢复默认
void restoreSystem(void);


/// 退出本应用程序，并重新运行。
void restartApplication(void);


/// 退出本应用程序。
void exitApplication(void);


/// 取启动状态标志
///
/// \retval >=0  获取成功；0-正常重启，1-异常重启，2-断电重启, 3-自动维护重启。
/// \retval <0  获取失败。
///
int getStartUpFlag(void);

/// 设置启动状态标志
///
/// \retval >=0  获取成功；0-正常重启，1-异常重启，2-断电重启, 3-自动维护重启。
/// \retval <0  设置失败。
///
void setStartUpFlag(int state);


/// 从cmos中读取各种状态数据,数据有效区域为[0x00, 0x0f]。
/// 
/// \param [in]  offs 数据操作在cmos中的偏移量
/// \param [out] buf 外部数据保存指针
/// \param [in]  len  外部数据长度(字节)
/// \retval <0  获取失败。
/// \retval =0  获取成功
///
int readCMOS(int offs, void * buf, int len);


/// 向CMOS中写入数据,数据有效区域为[0x00, 0x0f]。
///
/// \param [in] offs 写数据的偏移地址
/// \param [in] buf 写入的数据的指针
/// \param [in] len  写入数据的长度(字节)
/// \retval < 0 写数据失败
/// \retval = 0 写数据成功
///
int writeCMOS(int offs, void * buf, int len);


/// 开启看门狗定时器，如果看门狗计时到达设置的时间，会重启系统。
/// 使用的可能是专门的看门狗服务程序，而不一定是硬件看门狗。
/// 本函数应该在应用程序启动初期调用，且只能调用一次。
///
/// \param [in] millisecond 定时器周期，毫秒为单位。
/// \retval < 0 激活失败
/// \retval = 0 激活成功
///
int startWatchDogTimer(int millisecond);


/// 清空看门狗定时器
///
/// \retval < 0 清空失败
/// \retval = 0 清空成功
///
int resetWatchDogTimer(void);


/// 网络球单片机及IPC单片机升级接口
/// 
/// \param [in] data 数据包在内存中的指针，数据包头含程序标志，底层可以根据不同
///        的标志做不同处理。
/// \param [in] length 数据长度。
/// \param [out] written 已经写入的字节数，函数调用过程时会被定时更新，应用程序
///        不应该修改这个值。
/// \retval 0  成功
/// \retval <0  失败
int upgradeMCU(char *data, unsigned int length, unsigned int *written);

/// 升级数据块
typedef struct UpgradeDataBlock
{
	void *base;
	int length;
}UpgradeDataBlock;


/// 网络球单片机及IPC单片机升级接口，可以将多个不连续的数据块聚集到一起进行升级。
/// 数据头部分含程序标志，底层可以根据不同的标志做不同处理。
/// 
/// \param [in] blocks 指向UpgradeDataBlock结构数组的一个指针
/// \param [in] count 数组元素的个数
/// \param [out] written 已经写入的字节数，函数调用过程时会被定时更新，应用程序
///        不应该修改这个值。
/// \retval 0  成功
/// \retval <0  失败
int upgradeMCUV(const UpgradeDataBlock *blocks, unsigned int count, unsigned int *written);


/// 取得boot参数
/// \param [in] param  字段名字，如"bootargs", "ipaddr", "hwid"
/// \param [out] value 存储字符串参数的数组地址
/// \param [in] length 存储字符串参数的数组长度
/// \retval 0  成功
/// \retval <0  失败
int getBootParameter(char *param, char *value, int length);


/// 设置boot参数
/// \param [in] param  字段名字，如"bootargs", "ipaddr", "hwid"
/// \param [in] value 字符串参数
/// \retval 0  成功
/// \retval <0  失败
int setBootParameter(const char *param, const char *value);

/// 获取FPGA升级文件名字
///
/// \param [out] name FPGA升级文件名字
/// \param [in] len 缓冲长度
/// \retval < 0 失败
/// \retval = 0 成功
int getFpgaUpgradeName(char *name,int len);


/// 用加密算法加密用户密码
///
/// \param [in] password 用户密码字符串
/// \param [out] buffer 加密后的用户密码字符串
/// \param [in] buflen 加密字符串的缓存长度
/// \retval < 0 失败
/// \retval = 0 成功
int encryptionPassword(char *password, char *buffer, int buflen);

/// 系统子模块信息，256字节
typedef struct SubModule
{
	char name[32];				///< 模块名称
	char hardwareVersion[16];	///< 硬件版本
	char softwareVersion[16];	///< 软件版本
	char state;					///< 模块状态,0:正常，1:异常
	char placeholder[3];		///< 保留
	int reserved[47];			///< 保留
}SubModule;


/// 得到系统子模块信息
/// 
/// \param [out] modules 指向系统信息结构SystemInfo的指针。
/// \param [in/out] count 输入为需要取的模块总数，最大暂定为4；
///							输出为实际取到的模块数，不能超过输入的值。
/// \retval 0  获取成功。
/// \retval <0  获取失败或者没有子模块信息。
int getSubModules(SubModule * modules, int* count);

/// Rtc时间结构体
typedef struct RtcTime
{
	int  year;		///< 年。
	int  month;		///< 月，January = 1, February = 2, and so on.
	int  day;		///< 日。
	int  wday;		///< 星期，Sunday = 0, Monday = 1, and so on
	int  hour;		///< 时。
	int  minute;	///< 分。
	int  second;	///< 秒。
}RtcTime;


/// 从RTC芯片的读取时间
/// \param time 实时时间
/// \retval 0  获取成功。
/// \retval <0  获取失败。
int rtcReadTime(RtcTime *time);


/// 设置时间到RTC芯片内
/// \param time 实时时间
/// \retval 0  设置成功。
/// \retval <0  设置失败。
int rtcWriteTime(const RtcTime *time);

/// 认证模块枚举
typedef enum __VERIFY_MODULE {
	VERIFY_NONE,		/// 不进行认证
	VERIFY_IVS,			/// 算法模块认证
	VERIFY_SYSTEM,		/// 系统模块认证
}VERIFY_MODULE;

/// 加密芯片认证
///
/// \param [in] module 认证哪个模块
/// \retval < 0 认证失败
/// \retval = 0 认证成功
int verifyChip(VERIFY_MODULE module);

/// 向系统层申请内存
/// 关闭底层编码模块后，可以申请该模块占用的内存给应用特殊任务使用，如升级模块
/// 
/// \param [int,out] size 申请的字节数，申请成功后返回实际申请到的字节数
/// \retval == NULL 申请失败
/// \retval != NULL 申请到的内存地址
void *allocSystemMem(size_t *size);

/// 向系统层返还内存
/// \param [in] p 返还的内存地址
void freeSystemMem(void *p);


/* 定制化配置参数类型 */
typedef enum
{
    BallCamera = 0,         /* 配置球机机芯参数 */
    LenType = 1,            /* 镜头型号 */
    BallCameraType = 2,     /* 扩展配置球机机芯参数 */
    CustomType = 3,         /* 用户自定义信息 */
    CfgStrType = 4,         /* 定制化配置字符串 */
} SpecialType;


/* 球机机芯参数 */
typedef struct
{
    /* 球机机芯型号字符串,如: "BL-318-A3D" "BL-418-A2D" */
    char CameraName[32];
} BallCameraPrm;


/* 镜头型号 */
typedef struct
{
    /* 镜头型号字符串,如: "FG-3.3-10.5" "YT-2.8-8" */
    char LenName[32];
    char (*pLenTbl)[32];    /* 可选镜头列表 */
    unsigned int lenNum;    /* 可选镜头数 */
}LenTypePrm;


/* 球机机芯参数 */
typedef struct
{
    /* 球机机芯型号字符串,如: "BL-318-A3D" "BL-418-A2D" */
    char cameraName[32];
    char (*pCameraTbl)[32];    /* 可选球机列表 */
    unsigned int cameraNum;    /* 可选球机数 */
} BallCameraTypePrm;


/* */
typedef struct
{
    char *pCfgStr;          /* 定制化配置字符串 */
    int strlen;             /* 缓存大小 */
} CfgStrPrm;


/* 定制化配置参数 */
typedef struct
{
    int specialType;
    int reserved[31];
    
    union
    {
        BallCameraPrm ballCameraPrm;
        LenTypePrm lenTypePrm;
        BallCameraTypePrm ballCameraTypePrm;
        char customData[512];
        CfgStrPrm cfgStrPrm;
        int unionReserve[128];
    };
} SpecialCfgPrm;

/// 修改设备定制化参数
/// 调用该接口后需要重启设备才能生效,
/// 该接口只有与对应的定制程序匹配时才能生效
///
/// \param [int] pSpecialPrm HWID字符串
/// \retval < 0 失败
/// \retval = 0 成功
int setSpecialPrm(SpecialCfgPrm *pSpecialPrm);

/// 获取设备定制化参数
/// 该接口只有与对应的定制程序匹配时才能生效
///
/// \param [out] pSpecialPrm HWID字符串
/// \retval < 0 失败
/// \retval = 0 成功
int getSpecialPrm(SpecialCfgPrm *pSpecialPrm);

/// 获取复位按钮状态
///
/// \retval = 0 没有触发复位
/// \retval = 1 触发复位
int getResetStatus(void);

/// 系统信息类型
typedef enum 
{
	Bompid 		= 0,		///< bompid参数
	Hwid,					///< HWID参数
}systemInfoType;

/// 比较系统信息是否一致
/// \param [in] type 系统信息类型 参见systemInfoType
/// \param [in] data 数据内容
/// \param [in] size 数据长度
/// \retval = 0 信息一致 != 0 信息不一致
int systemInfoCmp(systemInfoType type, const char* data, int size);

/* 系统唤醒类型 */
typedef enum
{
    wakePowerUp = 0,        /* 设备上电 */
    wakeButtonTrigger,      /* 按键触发 */
    wakePirTrigger,         /* 人体感应触发 */
    wakeWifiTrigger,        /* wifi触发 */
    wakeHostReset,          /* 主机重启 */
    wakeWifiAbnormal,       /* wifi异常触发 */
} HostWakeType_t;

/// 获取系统启动唤醒类型
///
/// \param [int] pWakeType 唤醒类型,参见HostWakeType_t
/// \retval < 0 失败
/// \retval = 0 成功
int getHostWakeType(int *pWakeType);

/// 系统设置强制睡眠
///
/// \retval < 0 失败
/// \retval = 0 成功
int setHostSuspend(void);

/*保活数据结构体，128字节*/
typedef struct
{
    int enable;                 /*是否使能保活功能,0:不使能,1:使能*/
    int serverPort;             /*TCP服务器端的端口号*/
    char serverAddr[32];        /*服务器端IP地址*/
    int intervalTimer;          /*保活包发送周期,单位ms*/
    int retryIntervalTimer;     /*保活包重传周期，单位ms*/
    int retryMaxCount;          /*保活包重传次数*/
    int vendorIdLen;            /*厂商ID长度*/
    unsigned char *pVendorId;   /*厂商ID*/
    int devIdLen;               /*设备序列号长度*/
    unsigned char *pDevId;      /*设备序列号*/
    int reserved[15];
} keepaliveInfo_t;

/// 设备保活设置
///\param [in] pkeepalive 保活参数结构体指针
/// \retval < 0 失败
/// \retval = 0 成功
int setHostKeepalive(keepaliveInfo_t *pKeepalive);

/*唤醒信息数据结构体，128字节*/
typedef struct
{
    int enableSsid;             /*是否需要ssid唤醒设备*/
    char ssid[36];              /*需要唤醒的ssid*/
	int minutes;				/*自动唤醒时间,0为不唤醒,单位:分钟*/
    int reserved[21];
} wakeupInfo_t;

/// 设置唤醒信息
///\param [in] pWakeupInfo 唤醒参数结构体指针
/// \retval < 0 失败
/// \retval = 0 成功
int setHostWakeupInfo(wakeupInfo_t *pWakeupInfo);

/// @} end of group

#ifdef __cplusplus
}
#endif

#endif //__SYSTEM_API_H__

